#include "autoexclusivebutton.h"
#include <QMouseEvent>
#include <QPainter>
#include <QApplication>

using namespace ExecTerminalImplNS;

const int TEXT_X_POS = 25;
const int TEXT_Y_POS = 16;
const int TEXT_RIGHT_MARGIN = 23;
const QColor UNCHECKED_TEXT_COLOR(109, 142, 164);

AutoExclusiveButton::AutoExclusiveButton(QWidget * parent): QWidget(parent),
theUncheckedTextColor(UNCHECKED_TEXT_COLOR),
theTextXPos(TEXT_X_POS),
theTextYPos(TEXT_Y_POS),
theWidthForText(0),
theTextRightMargin(TEXT_RIGHT_MARGIN),
theChecked(false),
theDrawElidedText(true)
{
    init();
}

AutoExclusiveButton::AutoExclusiveButton(const QString & text, QWidget * parent): QWidget(parent),
theText(text),
theUncheckedTextColor(UNCHECKED_TEXT_COLOR),
theTextXPos(TEXT_X_POS),
theTextYPos(TEXT_Y_POS),
theWidthForText(0),
theTextRightMargin(TEXT_RIGHT_MARGIN),
theChecked(false)
{
    init();
}

void AutoExclusiveButton::init()
{
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
    theWidthForText = width();
}

QString AutoExclusiveButton::text()const
{
    return theText;
}

void AutoExclusiveButton::setText(const QString & aText)
{
    checkedSetValue(&theText, aText);
    if (aText != theText)
    {
        theText = aText;
        update();
        textChanged();
    }
}

int AutoExclusiveButton::textXPos()const
{
    return theTextXPos;
}
        
void AutoExclusiveButton::setTextXPos(int xPos)
{
    checkedSetValue(&theTextXPos, xPos);
}
        
int AutoExclusiveButton::textYPos()const
{
    return theTextYPos;
}

void AutoExclusiveButton::setTextYPos(int yPos)
{
    checkedSetValue(&theTextYPos, yPos);
}

int AutoExclusiveButton::widthForText()const
{
    return theWidthForText;
}

void AutoExclusiveButton::setWidthForText(int wdth)
{
    checkedSetValue(&theWidthForText, wdth);
}

void AutoExclusiveButton::setChecked(bool chckd)
{
    if (theChecked != chckd)
    {
        theChecked = chckd;
        if (theChecked)
        {
            const QList<AutoExclusiveButton*> & siblings = findSiblings();
            foreach (AutoExclusiveButton* sibling, siblings)
            {
                if (sibling != this)
                {
                    sibling->setChecked(false);
                }
            }
            repaint(); //flush paint event before invoking potentially expensive operation
            QApplication::flush();
            emit checked();
        }
        else
        {
            update();
        }
    }
}

bool AutoExclusiveButton::isChecked()const
{
    return theChecked;
}

void AutoExclusiveButton::enterEvent(QEvent *)
{
    update();
}

void AutoExclusiveButton::leaveEvent(QEvent *)
{
    update();
}

void AutoExclusiveButton::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    drawButtonText(&painter);
}

void AutoExclusiveButton::drawButtonText(QPainter * painter)
{
    painter->save();
    if (!theChecked && !underMouse())
    {
        painter->setPen(theUncheckedTextColor);
    }
    QFontMetrics m(painter->font());
    const QString & elided = theDrawElidedText ? 
        m.elidedText(theText, Qt::ElideRight, theWidthForText - theTextRightMargin - theTextXPos)
        : theText;
    painter->drawText(theTextXPos, theTextYPos, elided);    
    painter->restore();
}

void AutoExclusiveButton::mousePressEvent(QMouseEvent *e)
{
    if (e->button() != Qt::LeftButton) {
        e->ignore();
        return;
    }
    if (!theChecked)
    {
        setChecked(true);
    } else {
        e->ignore();
    }
}

void AutoExclusiveButton::resizeEvent(QResizeEvent *)
{
    theWidthForText = width();
}

QList<AutoExclusiveButton*> AutoExclusiveButton::findSiblings()const
{
    QList<AutoExclusiveButton*> candidates;
    QWidget * prnt = parentWidget();
    if (prnt) 
    {
        candidates =  qFindChildren<AutoExclusiveButton*>(prnt);
    }
    return candidates;
}

QColor AutoExclusiveButton::uncheckedTextColor()const
{
    return theUncheckedTextColor;
}

void AutoExclusiveButton::setUncheckedTextColor(const QColor & col)
{
    checkedSetValue(&theUncheckedTextColor, col);
}

void AutoExclusiveButton::setDrawElidedText(bool enable)
{
    checkedSetValue(&theDrawElidedText, enable);
}

